<?php

namespace core\lib\tool;

use Exception;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;


class Token
{
    /**
     * 设置安全配置文件
     *
     * @return array
     */
    public static function getSafeConfig(): array
    {
        return config('safe');
    }

    /**
     * 签发
     *
     * @param array $data
     * @param integer $exp
     * @return string
     */
    public static function issueToken(array $data, int $exp): string
    {
        $saveconfig = self::getSafeConfig();
        $nowtinme = time();
        $payload = [
            'iat'  => $nowtinme,           //签发时间
            'nbf'  => $nowtinme,           //(Not Before)：某个时间点后才能访问，比如设置time+30，表示当前时间30秒后才能使用
            'exp'  => $nowtinme + $exp,   //过期时间,这里设置2个小时
            'data' => $data
        ];
        return JWT::encode($payload, $saveconfig['key'], 'HS256');
    }

    /**
     * 验证token
     *
     * @param string $token
     * @throws Exception
     * @return array 
     */
    public static function verifyToken(string $token): array
    {

        try {
            $saveconfig = self::getSafeConfig();
            JWT::$leeway = 60; //当前时间减去60，把时间留点余地
            $decoded = JWT::decode($token, new key($saveconfig['key'], 'HS256')); //HS256方式，这里要和签发的时候对应
            return  (array)$decoded;
        } catch (\Firebase\JWT\SignatureInvalidException $e) {  //签名不正确
            throw new Exception($e->getMessage());
        } catch (\Firebase\JWT\BeforeValidException $e) {  // 签名在某个时间点之后才能用
            throw new Exception($e->getMessage());
        } catch (\Firebase\JWT\ExpiredException $e) {  // token过期
            throw new Exception($e->getMessage());
        } catch (Exception $e) {  //其他错误
            throw new Exception($e->getMessage());
        }
    }
}
